APCS in detail(ARM Procedure Call Standard) |
By way of example, when I was at college (back in '93), we had pascal inflicted on us. Well,
ordinarily this might have presented a problem. Pascal is designed to be a Good Teaching
Language, but GTL or not, it kept getting itself in the way of anything useful that should
have been possible. The file handling was just orbiting in some other galaxy...
Thus, I wrote my basic stuff in pascal. I defined a bunch of external procedures, such as
'printf()' and 'fgetc()'. So when linking my pascal program, I linked it with the Shared
C Library 'Stubs'. Hey presto, it worked!
Sadly, my hard work got me a D and a note not to be a smart ass. But I wasn't worried, I'm
a believer that the education system de-educates. So while my classmates were scratching
their heads trying to get Borland Turbo Pascal to do stuff, I knocked my code out in little
time at all on RISC OS with an APCS compliant language. I was happily calling C functions
from pascal, could have done vice versa. And if I wanted, writing some assembler and calling
that would have been just as simple.
A major benefit of this is that an APCS library, once written and properly documented, can be utilised from an APCS language.
The standard defines the use of registers - which may be corrupted and which must be
preserved, and how arguments are passed. This is the minimum requirement.
Furthermore, a data structure is defined which will allow a backtracer to deconstruct the
sequence of functions called, and details of parameters given. This information is invaluable
when debugging software.
The standard only really defines external procedure calls. If your code/language wishes to do things differently, it may provided that the external interface is kept as documented. In practise, it is usually best to follow the specification. That way, nothing gets confused.
The design criteria for APCS was arrived at following a lot of testing and experimentation.
Reg# APCS Purpose R0 a1 argument 1 / integer result R1 a2 argument 2 R2 a3 argument 3 R3 a4 argument 4 R4 v1 register variable R5 v2 register variable R6 v3 register variable R7 v4 register variable R8 v5 register variable R9 v6 register variable R10 sl stack limit R11 fp frame pointer R12 ip temporary workspace R13 sp stack pointer (full descending stack) R14 lr link address on calls/workspace R15 pc program counter and processor status (26 bit) F0 f0 floating point result F1 f1 floating point scratch register F2 f2 floating point scratch register F3 f3 floating point scratch register F4 f4 floating point preserved register F5 f5 floating point preserved register F6 f6 floating point preserved register F7 f7 floating point preserved register